#include "fs/devfs/devfs.h"
#include "fs/file.h"
#include "fs/fs.h"
#include "dev/dev.h"
#include "tools/klib.h"
#include "tools/log.h"

static devfs_dev_type_t devfs_dev_type_table[] = {
    {
        .name = "tty",
        .dev_type = DEV_TTY,
        .file_type = FILE_TTY,
    },
};

// 挂载文件系统
int devfs_mount(struct _fs_t * fs, int major, int minor)
{
    fs->type = FS_DEVFS;
    return 0;
}

void devfs_unmount(struct _fs_t * fs)
{

}

int devfs_open(struct _fs_t * fs, const char * path, file_t * file)
{
    // path = /tty:?
    for(int i=0; i<sizeof(devfs_dev_type_table)/sizeof(devfs_dev_type_table[0]); i++)
    {
        devfs_dev_type_t * dev_type = devfs_dev_type_table + i;
        int dev_type_name_len = kernel_strlen(dev_type->name);

        if(!kernel_strncmp(dev_type->name, path, dev_type_name_len))
        {
            int minor;
            if(kernel_strlen(path) > dev_type_name_len)
            {
                path_to_num(path + dev_type_name_len, &minor);
            }
            else
            {
                log_printf("Get dev minor failed. path = %s\n", path);
                break;
            }
            int dev_id = dev_open(dev_type->dev_type, minor, 0);

            if(dev_id < 0)
            {
                log_printf("open dev failed. path = %s\n", path);
                break;
            }
            // 初始化file
            file->dev_id = dev_id;
            file->fs = fs;
            file->pos = 0;
            file->ref = 1;
            file->size = 0;
            file->type = dev_type->file_type;
            // file->mode = 0;
            // kernel_strncpy(file->name, path, dev_type_name_len);
            return 0;
        }
    }
    return -1;
}

int devfs_read(char * buff, int size, file_t * file)
{
    return dev_read(file->dev_id, file->pos, buff, size);
}

int devfs_write(char * buff, int size, file_t * file)
{
    return dev_write(file->dev_id, file->pos, buff, size);
}

void devfs_close(file_t * file)
{
    dev_close(file->dev_id);
}

int devfs_ioctl(file_t * file, int cmd, int arg0, int arg1)
{
    return dev_control(file->dev_id, cmd, arg0, arg1);
}

  
int devfs_seek(file_t * file, uint32_t offset, int dir)
{
    return -1;
}

int devfs_stat(file_t * file, struct stat * st)
{
    return -1;
}



fs_op_t devfs_op = {
    .mount = devfs_mount,
    .unmount= devfs_unmount,                      // 取消挂载
    .open= devfs_open,
    .read= devfs_read,
    .write= devfs_write,
    .close= devfs_close,
    .seek= devfs_seek,
    .stat= devfs_stat,    
    .ioctl = devfs_ioctl,
    .closedir = 0,
    .opendir = 0,
    .readdir = 0,
};